package tests.lib;

import static org.junit.Assert.*;
import lib.SortingAndSearching;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class SortingAndSearchingTestCase {

	private String[] sampleStringData = {"Gatsby", "is", "the", "best", "engineer"};
	private Integer[] sampleIntegerData = {1,3,4,6,8,9,100,2,5};

	@After
	public void tearDown() throws Exception {
		this.sampleStringData = null;
	}

	@Test
	public void testPositiveCaseWithInteger() {
		Integer targetInt = 100;
		int expectedTargetLocation = 6;
		int locationOfTarget = SortingAndSearching.linearSearch(this.sampleIntegerData, 0, this.sampleIntegerData.length, targetInt);
		assertEquals(expectedTargetLocation, locationOfTarget);

		targetInt = 3;
		expectedTargetLocation = 1;
		locationOfTarget = SortingAndSearching.linearSearch(this.sampleIntegerData, 0, this.sampleIntegerData.length, targetInt);
		assertEquals(expectedTargetLocation, locationOfTarget);

		// Not found case
		targetInt = 1000;
		expectedTargetLocation = SortingAndSearching.NOT_FOUND;
		locationOfTarget = SortingAndSearching.linearSearch(this.sampleIntegerData, 0, this.sampleIntegerData.length, targetInt);
		assertEquals(expectedTargetLocation, locationOfTarget);
	}

	@Test
	public void testPositiveCaseWithString() {
		String targetString = "the";
		int expectedTargetLocation = 2;
		int locationOfTarget = SortingAndSearching.linearSearch(this.sampleStringData, 0, this.sampleStringData.length, targetString);
		assertEquals(expectedTargetLocation, locationOfTarget);

		targetString = "Gatsby";
		expectedTargetLocation = 0;
		locationOfTarget = SortingAndSearching.linearSearch(this.sampleStringData, 0, this.sampleStringData.length, targetString);
		assertEquals(expectedTargetLocation, locationOfTarget);

		targetString = "handsome";
		expectedTargetLocation = SortingAndSearching.NOT_FOUND;
		locationOfTarget = SortingAndSearching.linearSearch(this.sampleStringData, 0, this.sampleStringData.length, targetString);
		assertEquals(expectedTargetLocation, locationOfTarget);
	}

	@Test(expected=ArrayIndexOutOfBoundsException.class)
	public void testInvalidOverMaxIndexCaseWithArrayIndexOutOfBoundsException() {
		// maxIndex is greater than data size
		String targetString = "hansome";
		int maxIndex = 1000;
		int locationOfTarget = SortingAndSearching.linearSearch(this.sampleStringData, 0, maxIndex, targetString);
	}

	@Test(expected=ArrayIndexOutOfBoundsException.class)
	public void testInvalidLowerMaxIndexCaseWithArrayIndexOutOfBoundsException() {
		// maxIndex is greater than data size
		String targetString = "hansome";
		int maxIndex = -3;
		int locationOfTarget = SortingAndSearching.linearSearch(this.sampleStringData, 0, maxIndex, targetString);
	}

	@Test
	public void testMinIndexIsGreaterThanMaxIndexCase() {
		// maxIndex is greater than data size
		String targetString = "hansome";
		int minIndex = 4;
		int maxIndex = 1;
		int locationOfTarget = SortingAndSearching.linearSearch(this.sampleStringData, minIndex, maxIndex, targetString);
		int expectedTargetLocation = SortingAndSearching.NOT_FOUND;
		assertEquals(expectedTargetLocation, locationOfTarget);
	}
}
